#pragma once
#include "GameTimer.h"
#include <WindowsX.h>
#include "Common/d3dUtil.h"
#include "Common/MathHelper.h"
#include "Common/UploadBuffer.h"

#include<stack>
#include<unordered_set>
using namespace std;
using Microsoft::WRL::ComPtr;
using namespace DirectX;
using namespace DirectX::PackedVector;


#pragma comment(lib,"d3dcompiler.lib")
#pragma comment(lib, "D3D12.lib")
#pragma comment(lib, "dxgi.lib")

typedef Microsoft::WRL::ComPtr<ID3D12Device> PD3D12Device;
typedef Microsoft::WRL::ComPtr<ID3D12GraphicsCommandList> PCommandList;

typedef Microsoft::WRL::ComPtr<ID3D12Resource> PD3D12Resource;
typedef Microsoft::WRL::ComPtr<ID3DBlob> PD3DBlob;


extern string CreateUUid();

extern wstring ToWString(const string& str);
extern string ToString(const wstring& str);
class NameObjBase
{
public:
	NameObjBase(string strName) 
	{
		if (strName.empty())
		{
			strName = CreateUUid();
		}
		m_sName = (strName);
	}

	inline void SetName(string sName)
	{
		m_sName = sName;
	}

	inline string GetName() const
	{
		return m_sName;
	}
protected:
	string m_sName;
};

template<typename T>
class InstanceObj
{
public:
	static shared_ptr<T> GetInstance()
	{
		if (!m_pTexManage.get())m_pTexManage = make_shared<T>(T());
		return m_pTexManage;
	}
protected:
	static shared_ptr<T> m_pTexManage;

};
template<typename T>
shared_ptr<T> InstanceObj<T>::m_pTexManage = NULL;

template<typename T>
class VeObjManage
{
public:
	const T& Get(int inx) const { return m_vObj[inx]; }

	void Add(const T& obj) { m_vObj.push_back(obj); }

	int Count()const { return m_vObj.size(); }

	void Update(const vector<T>& v) { m_vObj = v; };

	void Clear() { m_vObj.clear(); };

	void SetData(const vector<T>& v) { m_vObj = v; };

	vector<T> GetData()
	{
		return m_vObj;
	}
protected:
	vector<T> m_vObj;
};


template<typename Key, typename Value>
class SortObjManage
{
public:
	void Add(const Key& key, const Value& v)
	{
		m_vObj[key] = v;
	}

	void Remove(const Key& key)
	{
		m_vObj.erase(key);
	}

	const Value& Get(string key) const
	{
		return m_vObj[key];
	}

	Value& Get(string key)
	{
		return m_vObj[key];
	}

	vector<Key> GetKeys()
	{
		vector<Key> ret;
		for (unordered_map<Key, Value>::iterator pos = m_vObj.begin(); pos != m_vObj.end(); ++pos)
		{
			ret.push_back(pos->first);
		}
		return ret;
	}

	int Count()
	{
		return m_vObj.size();
	}

	int GetKeyInx(const Key& v)
	{
		int iRet = -1;
		vector<Key> vKey = GetKeys();
		vector<Key>::iterator pos = std::find(vKey.begin(), vKey.end(), v);
		if (pos != vKey.end())
		{
			iRet = pos - vKey.begin();
		}
		return iRet;
	}
protected:
	unordered_map<Key, Value> m_vObj;
};




